home *** CD-ROM | disk | FTP | other *** search
Text File | 1996-08-15 | 11.8 KB | 402 lines | [TEXT/ALFA] |
- ####################################################################
- #
- # Much by Vince Darley.
- #
- # created: 3/7/95 {7:49:47 pm}
- # last update: 16/5/96
- # Author: Vince Darley
- # E-mail: <mailto:vince@das.harvard.edu>
- # mail: Division of Applied Sciences, Harvard University
- # Oxford Street, Cambridge MA 02138, USA
- # www: <http://www.fas.harvard.edu/~darley/>
- #
- ####################################################################
-
- ##
- # Here's a brief explanation of the smart fillParagraph routines
- #
- # 'fillParagraph'
- # If there's a selection, then fill all paragraphs in that
- # selection. If not then fill the paragraph surrounding the
- # insertion point. The definition of a 'paragraph' may be
- # mode dependent (see paraStart, paraFinish)
- #
- # 'fillOneParagraph'
- # Fills the single paragraph surrounding the insertion point.
- # If called with parameter '0', it doesn't bother to remember
- # where the insertion point was, which makes multiple paragraph
- # fills quicker when called by 'fillParagraph'
- #
- # 'rememberWhereYouAre'
- # Given the start of a paragraph and the point to remember,
- # this creates a record stored in '__g_remember_pos' so that
- # the following function can find that spot later, even after
- # the paragraph has had space/tabs/new-lines meddled with.
- #
- # 'goBackToWhereYouWere'
- # Given the beginning and end of a selection, where the beginning
- # corresponds to a previous call of 'rememberWhereYouAre', this
- # procedure will move the insertion point to the correct place.
- #
- # 'texParaCommands'
- # A variable containing the bulk of a regexp for paragraph
- # indicators in 'TeX' mode.
- #
- # 'paraStart'
- # Finds the start of the paragraph containing the insertion point.
- #
- # 'paraFinish'
- # Finds the end of the paragraph containing the insertion point.
- ##
-
- proc fillParagraph {} {
- if {[getPos] == [selEnd]} {
- fillOneParagraph
- } else {
- set start [getPos]
- set end [selEnd]
- set p $start
- while { $p < $end && $p < [maxPos]} {
- goto $p
- set p [fillOneParagraph 0]
- }
- goto $start
- }
- }
-
- proc rememberWhereYouAre { startPara pos } {
- global __g_remember_str
- set srem [expr $pos -20 < $startPara ? $startPara : $pos - 20]
- set __g_remember_str [quoteExpr2 [getText $srem $pos ] ]
- regsub -all "¥[ ¥t¥r¥]+" $__g_remember_str {[ ¥t¥r]+} __g_remember_str
- }
-
- proc goBackToWhereYouWere { start end } {
- global __g_remember_str
- if { $__g_remember_str != "" } {
- regexp -indices ".*(${__g_remember_str}).*" [getText $start $end] wholematch submatch
- goto [expr $start + 1 + [lindex $submatch 1]]
- } else {
- goto $start
- }
- }
-
- ##
- # -------------------------------------------------------------------------
- #
- # "getLeadingIndent" --
- #
- # Find the indentation of the line containing 'pos', and convert it
- # to a minimal form of tabs followed by spaces. If 'size'
- # is given, then the variable of that name is set to the length of
- # the indent. Similarly 'halftab' can be set to half a tab.
- # -------------------------------------------------------------------------
- ##
- proc getLeadingIndent { pos {size ""} {halftab ""} } {
- # get the leading whitespace of the current line
- set res [search -s -n -f 1 -r 1 "^¥[ ¥t¥]*" [lineStart $pos]]
-
- # convert it to minimal form: tabs then spaces, stored in 'front'
- getWinInfo a
- set sp [string range " " 1 $a(tabsize) ]
- regsub -all $sp [eval getText $res] "¥t" front
- regsub -all "¥[ ¥]+¥t" $front "¥t" front
- if { $size != "" } {
- upvar $size ind
- # get the length of the indent
- regsub -all "¥t" $front $sp lfront
- set ind [string length $lfront]
- }
-
- if { $halftab != "" } {
- upvar $halftab ht
- # get the length of half a tab
- set ht [string range " " 1 [expr $a(tabsize)/2]]
- }
-
- return $front
- }
-
- proc fillOneParagraph { {remember 1} } {
- global leftFillColumn fillColumn doubleSpaces
-
- set pos [getPos]
-
- set start [paraStart $pos]
- set end [paraFinish $pos]
- if $remember { rememberWhereYouAre $start $pos }
-
- # Get the leading whitespace of the current line and store length in 'left'
- set front [getLeadingIndent $pos left]
- # fill the text
- regsub -all "¥[ ¥t¥r¥]+" [string trim [getText $start $end]] " " text
- # turn single spaces at end of sentences into double
- if {$doubleSpaces} {regsub -all {(([^A-Z@]|¥¥@)[.?!]("|'|'')?([])])?) } $text {¥1 } text}
- # if {$doubleSpaces} {regsub -all {(([^A-Z@]|¥¥@)[.?!][])'"]?) } $text {¥1 } text}
-
- # temporarily adjust the fillColumns
- set ol $leftFillColumn
- set or $fillColumn
- set leftFillColumn 0
- set fillColumn [expr $fillColumn - $left]
-
- # break and indent the paragraph
- regsub -all "¥r" "¥r[string trimright [breakIntoLines $text]]" "¥r${front}" text
-
- # don't replace if nothing's changed
- if { "$text¥r" != "¥r[getText $start $end]" } {
- replaceText $start $end "[string range "$text" 1 end]¥r"
- if $remember { goBackToWhereYouWere $start [expr $start + [string length $text]] }
- }
-
- set leftFillColumn $ol
- set fillColumn $or
- # in case we wish to fill a region
- return $end
- }
-
-
- ##
- # -------------------------------------------------------------------------
- #
- # "paraStart" -- "paraFinish"
- #
- # Newly simplified version with fewer regexp '()' pairs. Also I think
- # it deals better with TeX comments than the old regexp.
- #
- # "Start": It's pretty clear for non TeX modes how this works. The only
- # key is that we start at the beginning of the current line and look back.
- # We then have a quick check for whether we found that very beginning (in
- # which case return it) or if not (in which case we have found the end of
- # the previous paragraph) we move forward a line.
- #
- # "Finish": The only addition is the need for an additional check for
- # stuff which explicitly ends lines.
- #
- # Results:
- # The start/finish position of the paragraph containing the given 'pos'
- #
- # --Version--Author------------------Changes-------------------------------
- # 1.1 <vince@das.harvard.edu> Cut down on '()' pairs
- # 1.2 Vince - March '96 Better filling for TeX tables ('hline')
- # 1.3 Johan Linde - May '96 Now sensitive to HTML elements
- # -------------------------------------------------------------------------
- ##
- proc paraStart {pos} {
- global mode texParaCommands htmlParaCommands
- if {$pos == [maxPos]} {incr pos -1}
- set pos [lineStart $pos]
- if { $mode == "TeX" || $mode == "Bib" } {
- set startPara {^[ ¥t]*$|¥¥¥¥[ ¥t]*$|%.*$|¥¥h+line[ ¥t]*$|¥$¥$[ ¥t]*$|^[ ¥t]*(¥¥(}
- append startPara $texParaCommands {)(¥[.*¥]|¥{.*¥}|・)*[ ¥t]*)+$}
- } elseif {$mode == "HTML"} {
- set startPara {^[ ¥t]*$|</?(}
- append startPara $htmlParaCommands {)([ ¥t¥r]+[^>]*>|>)}
- } else {
- set startPara {^([ ¥t]*|([¥¥%].*))$}
- }
- set res [search -s -n -f 0 -r 1 -l 0 "$startPara" $pos]
- if {![string length $res] || $res == "0 0" } {return 0}
- if { [lindex $res 0] == $pos } {
- return $pos
- } else {
- return [nextLineStart [lindex $res 0]]
- }
-
- }
-
- set texParaCommands {¥[|¥]|begin|end|(protect¥¥)?label|(sub)*section|subfigure|paragraph|centerline|centering|caption|chapter|item|bibitem|intertext}
- set htmlParaCommands {html|head|title|body|h[1-6]|p|div|blockquote|center|address|pre}
- append htmlParaCommands {|br|hr|wbr|basefont|ul|ol|li|dir|menu|dl|dd|dt|form|input}
- append htmlParaCommands {|select|option|textarea|caption|table|tr|frameset|frame|noframes}
- append htmlParaCommands {|map|area|applet|param|script|base|link|meta|isindex}
-
- proc paraFinish {pos} {
- global mode texParaCommands htmlParaCommands
- set pos [lineStart $pos]
- set end [maxPos]
- if { $mode == "TeX" || $mode == "Bib" } {
- set endPara {^[ ¥t]*$|¥$¥$[ ¥t]*$|^[ ¥t]*(¥¥(}
- append endPara $texParaCommands {)(¥[.*¥]|¥{.*¥}|・)*[ ¥t]*)+$}
- } elseif {$mode == "HTML"} {
- set endPara {^[ ¥t]*$|</?(}
- append endPara $htmlParaCommands {)([ ¥t¥r]+[^>]*>|>)}
- } else {
- set endPara {^([ ¥t]*|([¥¥%].*))$}
- }
-
- set res [search -s -n -f 1 -r 1 -l $end "$endPara" $pos]
- if {![string length $res]} {return $end}
- set cpos [lineStart [lindex $res 0] ]
- if { $cpos == $pos } {
- return [nextLineStart $cpos]
- }
- # A line which ends in '¥¥', '%...', '¥hline', '¥hhline'
- # signifies the end of the current paragraph in TeX mode
- # (the above checked for beginning of the next paragraph).
- if { $mode == "TeX" || $mode == "Bib" } {
- set res2 [search -s -n -f 1 -r 1 -l $end {((¥¥¥¥|¥¥h+line)[ ¥t]*|%.*)$} $pos]
- if [string length $res2] {
- if { [lindex $res2 0] < $cpos } {
- return [nextLineStart [lindex $res2 0]]
- }
- }
- }
-
- return $cpos
-
- }
-
-
- proc sentenceParagraph {} {
- set pos [getPos]
- set start [paraStart $pos]
- set finish [paraFinish $pos]
-
- set t [string trim [getText $start $finish]]
- set period [regexp {¥.$} $t]
- regsub -all "¥[ ¥t¥r¥]+" $t " " text
- regsub -all {¥. } $text "ニ" text
- set result ""
- foreach line [split [string trimright $text {.}] "ニ"] {
- if {[string length $line]} {
- append result [breakIntoLines $line] ".¥r"
- }
- }
- if {!$period && [regexp {¥.¥r} $result]} {
- set result [string trimright $result ".¥r"]
- append result "¥r"
- }
- if {$result != [getText $start $finish]} {
- replaceText $start $finish $result
- }
- goto $pos
- }
-
- proc getEndpts {} {
- if {[getPos] == [selEnd]} {
- set start [getPos]
- set finish [getMark]
- if {$start > $finish} {
- set temp $start
- set start $finish
- set finish $temp
- }
- } else {
- set start [getPos]
- set finish [selEnd]
- }
- return [list $start $finish]
- }
-
-
- proc fillRegion {} {
- global leftFillColumn
- set ends [getEndpts]
- set start [lineStart [lindex $ends 0]]
- set finish [lindex $ends 1]
- goto $start
- set text [fillText $start $finish]
- replaceText $start $finish [format "%$leftFillColumn¥s" ""] $text "¥r"
- }
-
- proc wrapParagraph {} {
- set pos [getPos]
- set start [paraStart $pos]
- set finish [paraFinish $pos]
- goto $start
- wrapText $start $finish
- goto $pos
- }
-
- proc wrapRegion {} {
- set ends [getEndpts]
- set start [lineStart [lindex $ends 0]]
- set finish [lindex $ends 1]
- if {$start == $finish} {
- set finish [maxPos]
- }
- wrapText $start $finish
- }
-
-
-
- # Remove text from window, transform, and insert back into window.
- proc fillText {from to} {
- global doubleSpaces
- set text [getText $from $to]
- regexp {^ *} $text front
- set text [string trim $text]
- regsub -all "¥[ ¥t¥r¥]+" $text " " text
- if {$doubleSpaces} {regsub -all {(¥.|¥?|¥!) } $text {¥1 } text}
- regsub -all "¥r" [string trimright [breakIntoLines $text]] "¥r${front}" text
- return $front$text
- }
-
- proc paragraphToLine {} {
- global fillColumn
- global leftFillColumn
- set fc $fillColumn
- set lc $leftFillColumn
- set fillColumn 10000
- set leftFillColumn 0
- fillRegion
- set fillColumn $fc
- set leftFillColumn $lc
- }
-
- proc lineToParagraph {} {
- global fillColumn
- global leftFillColumn
- set fc $fillColumn
- set fillColumn 75
- set lc $leftFillColumn
- set leftFillColumn 0
- fillRegion
- set fillColumn $fc
- set leftFillColumn $lc
- }
-
-
- #set sentEnd {[.!?](¥r| +)}
- set sentEnd {(¥r¥r|[.!?](¥r| +))}
- set sentBeg {[¥r ][A-Z]}
-
- proc nextSentence {} {
- global sentBeg sentEnd
- if {![catch {search -s -f 1 -r 1 $sentEnd [getPos]} mtch]} {
- if {![catch {search -s -f 1 -r 1 -i 0 $sentBeg [expr [lindex $mtch 1]-1]} mtch]} {
- goto [expr [lindex $mtch 0]+1]
- }
- }
- }
-
-
- proc prevSentence {} {
- global sentBeg sentEnd
- if {[catch {search -s -f 0 -r 1 $sentBeg [expr [getPos]-2]} mtch]} return
- if {![catch {search -s -f 0 -r 1 $sentEnd [lindex $mtch 1]} mtch]} {
- if {![catch {search -s -f 1 -r 1 -i 0 $sentBeg [expr [lindex $mtch 1]-1]} mtch]} {
- goto [expr [lindex $mtch 0]+1]
- }
- }
- }
- # 5 730 845 955
-
- #===============================================================================
- # Called by Alpha to do "soft wrapping"
- proc softProc {pos start next} {
- global leftFillColumn
- goto $start
- set finish [paraFinish $start]
- set text [fillText $start $finish]
- if {"${text}¥r" != [getText $start $finish]} {
- replaceText $start $finish [format "%$leftFillColumn¥s" ""] $text "¥r"
- return 1
- } else {
- return 0
- }
- }
-
-
-